﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.UI;
using System.Text.RegularExpressions;
using System.IO;
using MVCFoto.BLL;
using MVCFoto.Model;
using MVCFoto.Web.ViewData;
using MVCFoto.Web.ActionResults;

namespace MVCFoto.Web.Controllers
{

    [HandleError]    
    public class AccountController : Controller
    {

       
        private const int MIN_PASSWORD_LENGTH = 6;
        public AccountController()            
        {
        }

        #region 用户首页
        public ActionResult Index(int userId) 
        {
            BLL.User user = new User();
            UserIndexViewData viewData = new UserIndexViewData();            
            viewData.User = user.GetUser(userId);
            viewData.Friends = user.GetUserFriends(viewData.User.UserID);


            viewData.IsMyFriend = BLL.Friend.IsMyFriend(userId);
            if (viewData.User == null)
                throw new MVCFotoException("没有这个用户");
            BLL.Photo p = new Photo();
            Photo.AlbumPrivacy privacy = Photo.AlbumPrivacy.Public;
            //根据privacy控制隐私项的显示
            short gender_privacy = viewData.User.Gender;
            if (viewData.User.Privacy_Info != (int)BLL.User.Privacy.Public)
                viewData.User.Gender = -1;

            if (userId == BLL.User.MyID)
            {//self
                privacy = Photo.AlbumPrivacy.Private;
                viewData.User.Gender = gender_privacy;
            }
            else if (BLL.Friend.IsUserFriend(userId))
            {//friend
                privacy = Photo.AlbumPrivacy.Friend;
                if (viewData.User.Privacy_Info == (int)BLL.User.Privacy.Friend)
                    viewData.User.Gender = gender_privacy;
            }
            viewData.Photos = p.GetUserNewPhotos(userId, privacy);
            int itemcount = 0;
            viewData.Albums = p.GetUserAlbums(userId, privacy, 1, 5, out itemcount);
         //   ViewData["messages"] = TempData["messages"];
            return View(viewData);
        }
        #endregion

        #region 登录和注销
        public ActionResult LogOn()
        {
            if (User.Identity.IsAuthenticated)
                return RedirectToRoute("User", new { userid = BLL.User.MyID });
            ViewData["ReturnUrl"] = Request.QueryString["ReturnUrl"];
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
            Justification = "Needs to take same parameter type as Controller.Redirect()")]
        public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
        {
            ViewData["ReturnUrl"] = returnUrl;
            if (ValidateLogOn(userName, password))
            {
                if (!BLL.User.Login(userName, password, rememberMe))
                {
                    ModelState.AddModelError("_FORM", "用户名或密码错误.");
                    return View();
                }
                
                if (!String.IsNullOrEmpty(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {
                
                return View();
            }
        }

        public ActionResult LogOff()
        {

            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }
        #endregion

        #region 注册
        public ActionResult Register()
        {

            ViewData["PasswordLength"] = MIN_PASSWORD_LENGTH;

            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Register(string userName, string email, string password, string confirmPassword, int gender,string captcha)
        {

            ViewData["PasswordLength"] = MIN_PASSWORD_LENGTH;

            
            if (ValidateRegistration(userName, email, password, confirmPassword,captcha))
            {
                BLL.User user = new User();
                BLL.User.CreateUserStatus createStatus;
             
                Model.UserInfo userInfo = new MVCFoto.Model.UserInfo(userName,
                    FormsAuthentication.HashPasswordForStoringInConfigFile(password,"SHA1"),
                    email,
                    (short)gender,
                    "~/content/images/avatar/default.jpg",
                    string.Empty,
                    1,
                    DateTime.Now,
                    Request.UserHostAddress);
                
                user.AddUser(userInfo,out createStatus);

                if (createStatus == BLL.User.CreateUserStatus.Success)
                {
                    FormsAuthentication.SetAuthCookie(userName, false);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    ModelState.AddModelError("_FORM", ErrorCodeToString(createStatus));
                }
            }

            // If we got this far, something failed, redisplay form
            return View();
        }

        [Authorize]
        public ActionResult ChangePassword()
        {
            ViewData.Model = BLL.User.MyInfo;
            ViewData["PasswordLength"] = MIN_PASSWORD_LENGTH;

            return View();
        }
        #endregion

        #region 修改密码
        [Authorize]
        [AcceptVerbs(HttpVerbs.Post)]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
            Justification = "Exceptions result in password not being changed.")]
        public ActionResult ChangePassword(string currentPassword, string newPassword, string confirmPassword)
        {
            ViewData.Model = BLL.User.MyInfo;
            ViewData["PasswordLength"] = MIN_PASSWORD_LENGTH;

            if (!ValidateChangePassword(currentPassword, newPassword, confirmPassword))
            {
                return View();
            }
                 UserInfo myInfo = BLL.User.MyInfo;
                if (FormsAuthentication.HashPasswordForStoringInConfigFile(currentPassword,"SHA1")!= myInfo.Password)
                {
                    ModelState.AddModelError("_FORM", "您提供的原密码不正确.");
                    return View();
                    
                }
                else
                {
                   
                    BLL.User user = new User();
                    if (user.ChangePassword(myInfo.UserID, FormsAuthentication.HashPasswordForStoringInConfigFile(newPassword, "SHA1")))
                    {   //return RedirectToAction("Index", "Prompt", new
                        //                                            {
                        //                                                message = "密码修改成功",
                        //                                                url=Url.RouteUrl(this.RouteData.Values)
                        //                                             });
                        //TempData["messages"] = "密码修改成功";
                        //TempData["url"] = Url.RouteUrl(this.RouteData.Values);
                        //return RedirectToRoute("Prompt", new { redirect = true });
                        return new RedirectToPromptResult("密码修改成功", Url.RouteUrl(this.RouteData.Values), true);
                    }
                    else
                    {
                        ModelState.AddModelError("_FORM", "修改密码出错.");
                        return View();
                    }
                }

        }

        #endregion

        #region 个人资料修改
        [Authorize]
        public ActionResult Preferences()
        {           
            return View(BLL.User.MyInfo);
        }

        [Authorize]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Preferences(HttpPostedFileBase avatar, string userquote, int privacy)
        {
            UserInfo info = BLL.User.MyInfo;
            if (avatar == null && info.UserQuote == userquote && info.Privacy_Info == privacy)
                return View(info);
            else
            {
                
                if (avatar != null && avatar.ContentLength > 0)
                {   
                    if (MVCFotoSettings.AllowedTypes.IndexOf(Path.GetExtension(avatar.FileName).ToLower()) < 0)
                    {
                        ModelState.AddModelError("avatar", String.Format("只允许上传({0})类型的头像.", MVCFotoSettings.AllowedTypes));
                        return View(info);
                    }
                    else
                    {
                        //upload
                        
                        info.Avatar = Utility.Upload.UploadAvatar(avatar, info.UserID);
                    }
                }
               
                info.UserQuote = userquote;
                info.Privacy_Info = privacy;
                BLL.User user = new User();
                //防止更新用户登录次数
                info.Logins = 0;
                if (user.UpdateUser(info))
                {
                   
                    return new RedirectToPromptResult("更新个人信息成功",Url.RouteUrl(this.RouteData.Values),true);
                   // return RedirectToRoute("Prompt", new { redirect = true });
                }
                else
                {
                    ModelState.AddModelError("_FORM", "更新个人信息失败");
                    return View(info);
                }
                
            }

        }
        #endregion

        #region 好友
        [Authorize]
        public ActionResult Friends()
        {
            BLL.User user = new User();
            UserIndexViewData viewData = new UserIndexViewData();
            
            viewData.Friends = user.GetUserFriends(BLL.User.MyID);
            viewData.User = BLL.User.MyInfo;
            return View(viewData);
        }
        [Authorize]
        public ActionResult DeleteFriend(int userid)
        {
            TempData["messages"] = "您刚刚移除了该好友";
            return RedirectToAction("Index");
            BLL.Friend friend = new Friend();
            if (friend.DeleteFriend(BLL.User.MyID, userid))
            {
                TempData["messages"] = "您刚刚移除了该好友";
                return RedirectToAction("Index");
            }
            else
                return Redirect(Request.UrlReferrer.ToString());
        }
        #endregion

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.User.Identity is WindowsIdentity)
            {
                throw new InvalidOperationException("Windows authentication is not supported.");
            }
        }

        #region 数据验证

        private bool ValidateChangePassword(string currentPassword, string newPassword, string confirmPassword)
        {
            if (String.IsNullOrEmpty(currentPassword))
            {
                ModelState.AddModelError("currentPassword", "请输入原密码.");
            }
            if (newPassword == null || newPassword.Length < MIN_PASSWORD_LENGTH)
            {
                ModelState.AddModelError("newPassword",
                    String.Format(CultureInfo.CurrentCulture,
                         "新密码必须是{0}位以上字符.",
                         MIN_PASSWORD_LENGTH));
            }

          
            return ModelState.IsValid;
            
        }

        private bool ValidateLogOn(string userName, string password)
        {
            if (String.IsNullOrEmpty(userName))
            {
                ModelState.AddModelError("username", "必须输入用户名.");
            }
            if (String.IsNullOrEmpty(password))
            {
                ModelState.AddModelError("password", "必须输入登录密码.");
            }
          
            return ModelState.IsValid;
            
        }

        private bool ValidateRegistration(string userName, string email, string password, string confirmPassword,string vcode)
        {
            if (String.IsNullOrEmpty(vcode) || Session["VNUM"] == null || vcode.ToLower() != Session["VNUM"].ToString())
            {
                ModelState.AddModelError("captcha", "您输入的验证码不正确！");                
            }
            Session["VNUM"] = Guid.NewGuid();
           

            if (String.IsNullOrEmpty(userName))
            {
                ModelState.AddModelError("username", "请填写用户名.");
            }
            if(userName.Length < MVCFotoSettings.MinUserNameLength || userName.Length > 10)
                ModelState.AddModelError("username", String.Format("用户名长度只能是{0}-10之间.",MVCFotoSettings.MinUserNameLength));

            if (String.IsNullOrEmpty(email) && !Regex.IsMatch(email,@"^[_\.0-9a-zA-Z+-]+@([0-9a-zA-Z]+[0-9a-zA-Z-]*\.)+[a-zA-Z]{2,4}$"))
            {
                ModelState.AddModelError("email", "请填写正确的Email.");
            }
            if (password == null || password.Length < MIN_PASSWORD_LENGTH)
            {
                ModelState.AddModelError("password",
                    String.Format(CultureInfo.CurrentCulture,
                         "密码必须为{0}位以上.",
                         MIN_PASSWORD_LENGTH));
            }
           
            if (!String.Equals(password, confirmPassword, StringComparison.Ordinal))
            {
                ModelState.AddModelError("_FORM", "两次输入的密码不一致.");
            }
            return ModelState.IsValid;
            
        }

        private static string ErrorCodeToString(BLL.User.CreateUserStatus createStatus)
        {
            
            switch (createStatus)
            {
                case BLL.User.CreateUserStatus.DuplicateUserName:
                    return "用户名已经存在,请选择一个其他用户名.";
                case BLL.User.CreateUserStatus.DuplicateEmail:
                    return "Email地址已被使用，请换一个Email地址。";              
                default:
                    return "注册时出现未知错误，请检查您的输入后重试，如果仍然出现此错误提示，请联系管理员。";
            }
        }
        #endregion
    }

    


}
